package m

import (
	"GameServer/Common/utils"

	"github.com/globalsign/mgo/bson"

	log "github.com/sirupsen/logrus"

	"GameServer/Common/data"
	"GameServer/Game/cache"
	"GameServer/Game/dbmodule"
	"GameServer/Game/errors"
)

var (
	cardGameMulCombatTableName string = "cardGameMulCombat"
)

// 多人战斗卡牌游戏
type CardGameMulCombat struct {
	BaseM
	Uid                 bson.ObjectId   `bson:"_id" json:"_id"`
	Round               int64           `bson:"round" json:"round"` // 回合数
	Monster             *CardMonster    `bson:"monster" json:"monster"`
	Cards               []*Card         `bson:"cards" json:"cards"`                             // 用户手上卡牌列表
	CardBuffs           []*CardBuff     `bson:"cardBuffs" json:"cardBuffs"`                     // 卡牌buff
	Stone               int64           `bson:"stone" json:"stone"`                             // 沸点宝石
	AttBrustPercent     int64           `bson:"attBrustPercent" json:"attBrustPercent"`         // 玩家增伤百分比
	NextCardNumMinus    int64           `bson:"nexCardNumMinus" json:"nextCardNumMinus"`        // 下一回合卡牌减少数量
	DmgAccu             int64           `bson:"dmgAccu" json:"dmgAccu"`                         // 累计伤害
	DmgAccuBonusGain    map[int64]int64 `bson:"dmgAccuBonusGain" json:"dmgAccuBonusGain"`       // 已领取累伤奖励ID
	BossDefeatBonusGain map[int64]int64 `bson:"bossDefeatBonusGain" json:"bossDefeatBonusGain"` // 已领取BOSS击退奖励ID
	EndTime             int64           `bson:"endTime" json:"endTime"`                         // 本次战斗结束时间
	Status              int64           `bson:"status" json:"status"`                           // 状态 0 正常  1 胜利  2 失败 3 主动退出 4 已经领取奖励
	PlayerShield        int64           `bson:"playerShield" json:"playerShield"`               // 玩家护盾值
	ActivId             int64           `bson:"activId" json:"activId"`                         // 活动ID
	LastActivId         int64           `bson:"lastActivId" json:"lastActivId"`                 // 上次活动ID
	CardDeck            *CardDeck       `bson:"cardDeck" json:"cardDeck"`                       // 卡组
}

func NewCardGameMulCombat() cache.EntryI {
	return &CardGameMulCombat{
		Cards:               make([]*Card, 0),
		CardBuffs:           make([]*CardBuff, 0),
		Status:              -1,
		DmgAccuBonusGain:    make(map[int64]int64, 0),
		BossDefeatBonusGain: make(map[int64]int64, 0),
	}
}

// 保存信息
func (uCardGame *CardGameMulCombat) Save() (err error) {
	mdata := make(map[string]interface{}, 0)

	mdata["_id"] = uCardGame.Uid
	mdata["round"] = uCardGame.Round
	mdata["monster"] = uCardGame.Monster
	mdata["cards"] = uCardGame.Cards
	mdata["cardBuffs"] = uCardGame.CardBuffs
	mdata["stone"] = uCardGame.Stone
	mdata["attBrustPercent"] = uCardGame.AttBrustPercent
	mdata["nexCardNumMinus"] = uCardGame.NextCardNumMinus
	mdata["dmgAccu"] = uCardGame.DmgAccu
	mdata["endTime"] = uCardGame.EndTime
	mdata["status"] = uCardGame.Status
	mdata["playerShield"] = uCardGame.PlayerShield
	mdata["activId"] = uCardGame.ActivId
	mdata["lastActivId"] = uCardGame.LastActivId
	mdata["cardDeck"] = uCardGame.CardDeck

	if uCardGame.DmgAccuBonusGain != nil && len(uCardGame.DmgAccuBonusGain) > 0 {
		mdata["dmgAccuBonusGain"] = uCardGame.DmgAccuBonusGain
	}

	if uCardGame.BossDefeatBonusGain != nil && len(uCardGame.BossDefeatBonusGain) > 0 {
		mdata["bossDefeatBonusGain"] = uCardGame.BossDefeatBonusGain
	}

	err = dbmodule.MgoDB.GameDB.Upsert(cardGameMulCombatTableName, bson.M{"_id": uCardGame.Uid}, mdata)
	if err != nil {
		return
	}
	return
}

func (uCardGame *CardGameMulCombat) Load(key interface{}) (err error) {
	switch key.(type) {
	case string:
		if key.(string) == "" {
			return errors.New("无效的key load, key empty")
		}
		uCardGame.Uid = bson.ObjectIdHex(key.(string))
	case bson.ObjectId:
		uCardGame.Uid = key.(bson.ObjectId)
	default:
		log.WithFields(log.Fields{
			"method": "CardGameMulCombat_Load",
			"data":   key,
		}).Error("无效的key load")
		return errors.New("无效的key load")
	}
	return uCardGame.LoadData()
}

// 加载数据
func (uCardGame *CardGameMulCombat) LoadData() (err error) {
	err = dbmodule.MgoDB.GameDB.FindOne(cardGameMulCombatTableName, bson.M{"_id": uCardGame.Uid}, nil, &uCardGame)
	if err != nil {
		if err.Error() == "not found" {
			return nil
		}
		return
	}
	if uCardGame.DmgAccuBonusGain == nil {
		uCardGame.DmgAccuBonusGain = make(map[int64]int64, 0)
	}
	if uCardGame.BossDefeatBonusGain == nil {
		uCardGame.BossDefeatBonusGain = make(map[int64]int64, 0)
	}
	return
}

// 更新数据
func (uCardGame *CardGameMulCombat) Update(val *CardGameMulCombat) {
	Cache.Put(cardGameMulCombatTableName, uCardGame.Uid.Hex(), val)
	val.UpdateData()
}

// 删除数据
func (uCardGame *CardGameMulCombat) Delete() (err error) {
	Cache.Remove(cardGameMulCombatTableName, uCardGame.Uid.Hex())
	return dbmodule.MgoDB.GameDB.Remove(cardGameMulCombatTableName, bson.M{"_id": uCardGame.Uid})
}

// 获取多人战斗数据M，不会检测EndTime有效性
func (u *User) GetCardGameMulCombat() (r *CardGameMulCombat) {
	v, _ := Cache.Get(cardGameMulCombatTableName, u.Uid.Hex())
	r = v.(*CardGameMulCombat)
	return
}

// 获取多人战斗数据M，进行活动ID，与EndTime检测
func (u *User) GetCardGameMulCombatByActId(actId int64, combatEndTime int64) (r *CardGameMulCombat) {
	v, _ := Cache.Get(cardGameMulCombatTableName, u.Uid.Hex())
	r = v.(*CardGameMulCombat)
	nowTime := utils.TNow().Unix()
	if r != nil {
		if r.ActivId != actId || (r.EndTime+86400) < nowTime {
			r.Uid = u.Uid
			r.LastActivId = r.ActivId
			r.ActivId = actId
			r.Round = 1
			//Monster为空，会在8101进入战斗时候重置怪物信息
			r.Cards = make([]*Card, 0)
			r.CardBuffs = make([]*CardBuff, 0)
			r.Stone = data.CardManaEnum.InitalMana
			r.AttBrustPercent = 0
			r.NextCardNumMinus = 0
			r.DmgAccu = 0
			r.DmgAccuBonusGain = make(map[int64]int64, 0)
			r.BossDefeatBonusGain = make(map[int64]int64, 0)
			r.Status = 0
			r.PlayerShield = 0
			r.EndTime = combatEndTime
			r.Update(r)
		}
	}
	return
}

// 是否已经获得，累计伤害奖励，传入奖励ID
func (uCardGame *CardGameMulCombat) IsGainBonus_DmgAccu(bonusId int64) (isGain bool) {
	_, ok := uCardGame.DmgAccuBonusGain[bonusId]
	if ok {
		isGain = true
	} else {
		isGain = false
	}
	return isGain
}

// 是否已经获得，BOSS击退奖励，传入BOSS的Tid
func (uCardGame *CardGameMulCombat) IsGainBonus_BossDefeat(bossTid int64) (isGain bool) {
	_, ok := uCardGame.BossDefeatBonusGain[bossTid]
	if ok {
		isGain = true
	} else {
		isGain = false
	}
	return isGain
}

// 设置该ID的，累伤奖励，为已经获取状态
func (uCardGame *CardGameMulCombat) SetGainBonus_DmgAccu(bonusId int64) {
	if uCardGame.DmgAccuBonusGain == nil {
		uCardGame.DmgAccuBonusGain = make(map[int64]int64, 0)
	}
	uCardGame.DmgAccuBonusGain[bonusId] = 1
	uCardGame.Update(uCardGame)
}

// 设置该ID的，BOSS击退奖励，为已经获取状态
func (uCardGame *CardGameMulCombat) SetGainBonus_BossDefeat(bossTid int64) {
	if uCardGame.BossDefeatBonusGain == nil {
		uCardGame.BossDefeatBonusGain = make(map[int64]int64, 0)
	}
	uCardGame.BossDefeatBonusGain[bossTid] = 1
	uCardGame.Update(uCardGame)
}

func (uCardGame *CardGameMulCombat) UpdateDmgAccu(newDmgAccu int64) {
	uCardGame.DmgAccu = newDmgAccu
	uCardGame.Update(uCardGame)
}

// 获取用户卡组
func (uCardGame *CardGameMulCombat) GetCardDeck(LockBlockTid int64) (cardDeck *CardDeck) {
	needUpdate := false
	if uCardGame.CardDeck == nil {
		uCardGame.CardDeck = &CardDeck{
			LockBlockTid: LockBlockTid,
			ExtraCard:    make(map[int64]int64, 0),
			DeckIndex:    0,
			CombatDecks:  make([]int64, 0),
		}
		needUpdate = true
	}
	if uCardGame.CardDeck.LockBlockTid != LockBlockTid {
		uCardGame.CardDeck = &CardDeck{
			LockBlockTid: LockBlockTid,
			ExtraCard:    make(map[int64]int64, 0),
			DeckIndex:    0,
			CombatDecks:  make([]int64, 0),
		}
		needUpdate = true
	}
	if uCardGame.CardDeck.ExtraCard == nil {
		uCardGame.CardDeck.ExtraCard = make(map[int64]int64, 0)
		needUpdate = true
	}
	if needUpdate {
		uCardGame.Update(uCardGame)
	}
	return uCardGame.CardDeck
}
